package parser

import (
	"fmt"

	"ddl_checker/pkg/analyzer"
	"ddl_checker/pkg/types"
)

// DDLStatement 表示解析后的DDL语句 (兼容性别名)
type DDLStatement = types.SQLStatement

// StatementType DDL语句类型枚举 (兼容性别名)
type StatementType = types.StatementType

// ParserUsed 使用的解析器枚举 (兼容性别名)
type ParserUsed = types.ParserUsed

const (
	ParserUsedPgQuery = types.ParserUsedPgQuery
	ParserUsedTiDB    = types.ParserUsedTiDB
	ParserUsedUnknown = types.ParserUsedUnknown
)

// HybridAnalyzer 混合SQL分析器
// 优先使用pg_query_go解析，失败后使用TiDB解析
// 同时实现了analyzer.SQLAnalyzer接口和原有的DDLStatement方法
type HybridAnalyzer struct {
	pgQueryAnalyzer analyzer.SQLAnalyzer
	tidbAnalyzer    analyzer.SQLAnalyzer
}

// NewHybridAnalyzer 创建新的混合分析器
func NewHybridAnalyzer() *HybridAnalyzer {
	return &HybridAnalyzer{
		pgQueryAnalyzer: analyzer.NewPGQueryAnalyzer(false),
		tidbAnalyzer:    analyzer.NewTiDBAnalyzer(false),
	}
}

// ParseBatch 实现analyzer.SQLAnalyzer接口，返回analyzer.SQLStatement类型
func (h *HybridAnalyzer) ParseBatch(sql string, separator string) ([]*analyzer.SQLStatement, error) {
	var lastError error

	// 首先尝试使用pg_query_go解析
	analyzerStmts, err := h.pgQueryAnalyzer.ParseBatch(sql, separator)
	if err == nil && len(analyzerStmts) > 0 {
		return analyzerStmts, nil
	}

	// 如果pg_query_go失败，使用TiDB解析器
	lastError = err
	analyzerStmts, err = h.tidbAnalyzer.ParseBatch(sql, separator)
	if err == nil && len(analyzerStmts) > 0 {
		return analyzerStmts, nil
	}

	// 两个解析器都失败，返回错误
	if lastError != nil {
		return nil, fmt.Errorf("all analyzers failed. pg_query error: %v, tidb error: %v", lastError, err)
	}

	return nil, fmt.Errorf("no statements found")
}

// ParseSingle 实现analyzer.SQLAnalyzer接口，返回analyzer.SQLStatement类型
func (h *HybridAnalyzer) ParseSingle(sql string) (*analyzer.SQLStatement, error) {
	var lastError error

	// 首先尝试使用pg_query_go解析
	analyzerStmt, err := h.pgQueryAnalyzer.ParseSingle(sql)
	if err == nil && analyzerStmt != nil {
		return analyzerStmt, nil
	}

	// 如果pg_query_go失败，使用TiDB解析器
	lastError = err
	analyzerStmt, err = h.tidbAnalyzer.ParseSingle(sql)
	if err == nil && analyzerStmt != nil {
		return analyzerStmt, nil
	}

	// 两个解析器都失败，返回错误
	if lastError != nil {
		return nil, fmt.Errorf("all analyzers failed. pg_query error: %v, tidb error: %v", lastError, err)
	}

	return nil, fmt.Errorf("no statement found")
}

// ParseBatchDDL 保留原有的DDLStatement方法，用于向后兼容
func (h *HybridAnalyzer) ParseBatchDDL(sql string, separator string) ([]*DDLStatement, error) {
	var statements []*DDLStatement
	var lastError error

	// 首先尝试使用pg_query_go解析
	analyzerStmts, err := h.pgQueryAnalyzer.ParseBatch(sql, separator)
	if err == nil && len(analyzerStmts) > 0 {
		statements = h.convertToDDLStatements(analyzerStmts)
		return statements, nil
	}

	// 如果pg_query_go失败，使用TiDB解析器
	lastError = err
	analyzerStmts, err = h.tidbAnalyzer.ParseBatch(sql, separator)
	if err == nil && len(analyzerStmts) > 0 {
		statements = h.convertToDDLStatements(analyzerStmts)
		return statements, nil
	}

	// 两个解析器都失败，返回错误
	if lastError != nil {
		return nil, fmt.Errorf("all analyzers failed. pg_query error: %v, tidb error: %v", lastError, err)
	}

	return nil, fmt.Errorf("no statements found")
}

// ParseSingleDDL 保留原有的DDLStatement方法，用于向后兼容
func (h *HybridAnalyzer) ParseSingleDDL(sql string) (*DDLStatement, error) {
	var lastError error

	// 首先尝试使用pg_query_go解析
	analyzerStmt, err := h.pgQueryAnalyzer.ParseSingle(sql)
	if err == nil && analyzerStmt != nil {
		return h.convertToDDLStatement(analyzerStmt), nil
	}

	// 如果pg_query_go失败，使用TiDB解析器
	lastError = err
	analyzerStmt, err = h.tidbAnalyzer.ParseSingle(sql)
	if err == nil && analyzerStmt != nil {
		return h.convertToDDLStatement(analyzerStmt), nil
	}

	// 两个解析器都失败，返回错误
	if lastError != nil {
		return nil, fmt.Errorf("all analyzers failed. pg_query error: %v, tidb error: %v", lastError, err)
	}

	return nil, fmt.Errorf("no statement found")
}

// ValidateSQL 验证SQL语句，优先使用pg_query_go，失败后使用TiDB
func (h *HybridAnalyzer) ValidateSQL(sql string) (bool, string) {
	// 首先尝试使用pg_query_go验证
	valid, msg := h.pgQueryAnalyzer.ValidateSQL(sql)
	if valid {
		return true, msg
	}

	// 如果pg_query_go验证失败，使用TiDB解析器
	valid, msg = h.tidbAnalyzer.ValidateSQL(sql)
	if valid {
		return true, msg
	}

	// 两个解析器都验证失败，返回false
	return false, fmt.Sprintf("both analyzers failed to validate SQL: %s", msg)
}

// SplitStatements 分割SQL语句，优先使用pg_query_go，失败后使用TiDB
func (h *HybridAnalyzer) SplitStatements(sql string, separator string) ([]string, error) {
	var lastError error

	// 首先尝试使用pg_query_go分割
	statements, err := h.pgQueryAnalyzer.SplitStatements(sql, separator)
	if err == nil && len(statements) > 0 {
		return statements, nil
	}

	// 如果pg_query_go失败，使用TiDB解析器
	lastError = err
	statements, err = h.tidbAnalyzer.SplitStatements(sql, separator)
	if err == nil && len(statements) > 0 {
		return statements, nil
	}

	// 两个解析器都失败，返回错误
	if lastError != nil {
		return nil, fmt.Errorf("all analyzers failed. pg_query error: %v, tidb error: %v", lastError, err)
	}

	return nil, fmt.Errorf("no statements found")
}

// convertToDDLStatement 将analyzer.SQLStatement转换为DDLStatement
func (h *HybridAnalyzer) convertToDDLStatement(stmt *analyzer.SQLStatement) *DDLStatement {
	return &types.SQLStatement{
		OriginalSQL:   stmt.OriginalSQL,
		IsValid:       stmt.IsValid,
		StatementType: stmt.StatementType,
		Tables:        stmt.Tables,
		Columns:       stmt.Columns,
		Operations:    stmt.Operations,
		Error:         stmt.Error,
		Schema:        stmt.Schema,
		TableName:     stmt.TableName,
		ParserUsed:    stmt.ParserUsed,
	}
}

// convertToDDLStatements 将analyzer.SQLStatement数组转换为DDLStatement数组
func (h *HybridAnalyzer) convertToDDLStatements(statements []*analyzer.SQLStatement) []*DDLStatement {
	result := make([]*DDLStatement, len(statements))
	for i, stmt := range statements {
		result[i] = h.convertToDDLStatement(stmt)
	}
	return result
}

// ParseWithFallback 带回退机制的解析方法
// 返回解析结果和实际使用的解析器类型
func (h *HybridAnalyzer) ParseWithFallback(sql string) ([]*DDLStatement, ParserUsed, error) {
	var statements []*DDLStatement
	var lastError error
	var usedParser ParserUsed

	// 首先尝试使用pg_query_go解析
	analyzerStmts, err := h.pgQueryAnalyzer.ParseBatch(sql, ";")
	if err == nil && len(analyzerStmts) > 0 {
		usedParser = ParserUsedPgQuery
		// 转换为DDLStatement并标记使用的解析器
		statements = h.convertToDDLStatements(analyzerStmts)
		for _, stmt := range statements {
			stmt.ParserUsed = usedParser
		}
		return statements, usedParser, nil
	}

	// 如果pg_query_go失败，使用TiDB解析器
	lastError = err
	analyzerStmts, err = h.tidbAnalyzer.ParseBatch(sql, ";")
	if err == nil && len(analyzerStmts) > 0 {
		usedParser = ParserUsedTiDB
		// 转换为DDLStatement并标记使用的解析器
		statements = h.convertToDDLStatements(analyzerStmts)
		for _, stmt := range statements {
			stmt.ParserUsed = usedParser
		}
		return statements, usedParser, nil
	}

	// 两个解析器都失败，返回错误
	if lastError != nil {
		return nil, ParserUsedUnknown, fmt.Errorf("all analyzers failed. pg_query error: %v, tidb error: %v", lastError, err)
	}

	return nil, ParserUsedUnknown, fmt.Errorf("no statements found")
}
